# -*- coding: utf8 -*-
from datetime import date
from dateutil.relativedelta import relativedelta
from email.utils import formataddr
import math
import os.path
import subprocess
from time import strftime
import pkg_resources
import tempfile

from pyramid.httpexceptions import (
    HTTPFound,
    HTTPNotFound,
    HTTPForbidden,
    )

from pyramid.renderers import render, get_renderer
from pyramid.response import Response
from pyramid.security import (
    authenticated_userid,
    remember,
    forget,
    )
from pyramid.view import (
    view_config,
    forbidden_view_config,
    )

from pyramid_mailer import get_mailer
from pyramid_mailer.message import Message, Attachment

from .models import (
    DBSession,
    get_eleve_agence_email,
    get_eleve_cpt_extrait,
    get_eleve_info,
    get_eleve_stage,
    get_eleves_by_code,
    get_eleves_by_last_connection,
    get_eleves_by_name,
    get_date_examen,
    get_dates_fin_validite,
    get_rdv_by_code,
    update_details,
    update_last_connection,
    update_password
    )

from .security import USERS, groupfinder

def to_decimal(x):
    import decimal
    return decimal.Decimal(str(x))

def to_euroz(x):
    """Takes a float and returns a string"""
    if x == 0:
       return ""
    else:
       return (u"%.2f €" % x).replace('.', ',')

def to_euro(x):
    """Takes a float and returns a string"""
    return (u"%.2f €" % x).replace('.', ',')

def to_percent(x):
    """Takes a float and returns a string"""
    return (u"%.2f " % x).replace('.', ',') + "%"

#  - - - - - - - - - - - - - - - - - - - - - - - - - - 

@view_config(route_name='carnet_rdv', renderer='templates/carnet_rdv.pt', permission='view')
def carnet_rdv(request):
    """Carnet de rendez-vous view"""
    logged_in = authenticated_userid(request)
    # get rendez-vous
    items = get_rdv_by_code(logged_in)

    return {
        'page_title': u"Carnet de rendez-vous",
        'items': items,
        }


@view_config(route_name='change_details',
        renderer='templates/change_details.pt', permission='view')
def change_details(request):
    url = request.route_url('change_details')
    logged_in = authenticated_userid(request)
    # user = admin ?
    if logged_in == "000000":
       return HTTPFound(location=request.route_url('home'))
    message = u''
    results = get_eleves_by_code(logged_in)
    if results:
        member = results[0]
    else:
        member = None  

    if 'form.submitted' in request.params:
        new_values = {}
        # import pdb;pdb.set_trace()
        for param, db_value in member.items():
            if param in request.params and request.params[param] != db_value:
                new_values[param] = request.params[param]

        if new_values:
            update_details(logged_in, new_values)
            request.session.flash(u"Vos coordonnées ont été mises à jour avec succès.")

            # envoyer un message à la secrétaire
            if member.email:
                # lire l'adresse email de l'agence de l'élève
                agence_email = get_eleve_agence_email(logged_in)[0]
                # Fabrication du corps du Message
                email = member.email
                body = u"""
Bonjour,

%s, code élève : %s 
vient de changer ses coordonnées via monespace.marietton.com.

Cordialement,
Espace Client MARIETTON
                """ % (member.NOMPREN, logged_in)
                message = Message(subject=u"[monespace] Changement de coordonnées",
                                  sender=request.registry.settings['monaem.admin_email'],
                                  recipients=[agence_email.email],
                                  body=body)
                mailer = get_mailer(request)
                mailer.send(message)

            return HTTPFound(location=request.route_url('home'))

    return {
        'page_title': u"Changer mes coordonnées",
        'url': url,
        'member': member,
        'message': message,
    }


@view_config(route_name='change_password',
        renderer='templates/change_password.pt', permission='view')
def change_password(request):
    url = request.route_url('change_password')
    logged_in = authenticated_userid(request)
    message = ''

    results = get_eleves_by_code(logged_in)
    if results:
        member = results[0]
    else:
        member = None  # user = admin

    if 'form.submitted' in request.params:
        old_password = request.params['old_password']
        new_password = request.params['new_password1']
        if results[0].motdepasse == old_password:
            update_password(logged_in, new_password)
            request.session.flash(u"Votre mot de passe a été mis à jour avec succès.")
            return HTTPFound(location=request.route_url('home'))
        else:
            message = u"Le code accès fourni est incorrect."
    return {
        'page_title': u"Changer mon mot de passe",
        'url': url,
        'member': member,
        'message': message,
    }


@view_config(route_name='date_examen', renderer='templates/date_examen.pt', permission='view')
def date_examen(request):
    """ Date examen view """
    logged_in = authenticated_userid(request)
    examen = get_date_examen(logged_in)
    import pdb;pdb.set_trace()
    if examen:
        date = examen[0],
        heure = examen[1],
        type = examen[2],
        adresse = examen[3],
        lieu = examen[4],
        resultat = examen[5],
    else:
        date = "",
        heure = None,
        type = None,
        adresse = None,
        lieu = None,
        resultat = None,

    return {
        'page_title': u"Prochaine date d'examen",
        'date': date,
        'heure': heure,
        'type': type,
        'adresse': adresse,
        'lieu': lieu,
        'resultat': resultat,
        }


@view_config(route_name='dates_stage', renderer='templates/dates_stage.pt', permission='view')
def dates_stage(request):
    """ Dates de stage view """
    logged_in = authenticated_userid(request)
    if logged_in == "000000":
       return HTTPFound(location=request.route_url('home'))

    items = get_eleve_stage(logged_in)
    if items:
       item = items[0]
    else:
       item = None
   
    # import pdb;pdb.set_trace()

    return {
        'page_title': u"Dates de stage",
        'item': item,
        }


@view_config(route_name='email_password',
        renderer='templates/email_password.pt')
def email_password(request):
    url = request.route_url('email_password')
    message = u''
    if 'form.submitted' in request.params:
        login = request.params['login']
        results = get_eleves_by_code(login)
        if results:
            member = results[0]
            if member.email:
                # Fabrication du corps du Message
                email = member.email
                body = u"""
Cher(e) client(e),

Vous aviez oublié votre mot de passe. Nous vous le retournons puisque vous nous l'avez demandé aujourd'hui.
Votre code élève : %s 
Votre mot de passe : %s 
Nous vous conseillons d'imprimer et/ou de conserver ce message.

Cordialement,
Espace Client MARIETTON
                """ % (login, member.motdepasse)
                message = Message(subject=u"[MARIETTON] Oubli de mot de passe",
                                  sender=request.registry.settings['monaem.admin_email'],
                                  recipients=[email],
                                  body=body)
                mailer = get_mailer(request)
                mailer.send(message)
                request.session.flash(u"Votre mot de passe vous a été envoyé à votre adresse : %s." % email)
                return HTTPFound(location=request.route_url('login_as', login=login))
            else:
                message = u"L'adresse e-mail de cet élève n'est pas renseignée. Contactez votre agence."
        else:
            message = u"Ce code Elève n'existe pas."

    return {
        'page_title': u"Mot de passe oublié ?",
        'url': url,
        'message': message,
    }


@view_config(route_name='extrait_compte', renderer='templates/extrait_compte.pt', permission='view')
def extrait_compte(request):
    """Extrait de compte view"""
    logged_in = authenticated_userid(request)
    url = request.route_url('extrait_compte')

    member_info = get_eleve_info(logged_in)
    # get compte
    items = get_eleve_cpt_extrait(logged_in)
    # calculate sums
    sum_to_pay = 0
    sum_paid = 0
    for item in items:
        sum_to_pay += float(item.DEBIT)
        sum_paid += float(item.CREDIT)

    if 'form.submitted' in request.params:
       solde = request.params['mtsolde']
       return HTTPFound(location=request.route_url('reglement', mttotal=solde))

    return {
        'page_title': u"Mon en-cours",
        'items': items,
        'sum_to_pay': to_euro(sum_to_pay),
        'sum_paid': to_euro(sum_paid),
        'today': strftime("%d/%m/%Y"),
        'solde': float(sum_to_pay - sum_paid),
        'remain_to_pay': to_euro(sum_to_pay - sum_paid),
        'member_has_email': bool(member_info['email']),
        'url': url
        }


@view_config(route_name='home', renderer='templates/home.pt', permission='view')
def home(request):
    """Home view"""
    logged_in = authenticated_userid(request)
    # get date de fin code
    items = get_dates_fin_validite(logged_in)
    date_fin_code = items[0]
    date_fin_vm = items[1]
    groups = groupfinder(logged_in, request)
    if 'group:administrators' in groups:
        is_admin = True
    else:
        is_admin = False

    return {
        'page_title': u"Mon calendrier",
        'date_fin_code': date_fin_code,
        'date_fin_vm' : date_fin_vm,
        'is_admin' : is_admin
        }


@view_config(route_name='faq_cgv', renderer='templates/faq_cgv.pt')
def faq_cgv(request):
    return {
        'page_title': u"Conditions Générales de vente",
    }


@view_config(route_name='faq_mentions_legales', renderer='templates/faq_mentions_legales.pt')
def faq_mentions_legales(request):
    return {
        'page_title': u"Mentions légales",
    }


@view_config(route_name='faq_pieces_a_presenter', renderer='templates/faq_pieces_a_presenter.pt')
def faq_pieces_a_presenter(request):
    return {
        'page_title': u"Pièces à présenter lors d'un examen",
    }


@view_config(route_name='fiche_inscription', renderer='templates/fiche_inscription.pt', permission='view')
def fiche_inscription(request):
    """ Fiche inscription view """
    logged_in = authenticated_userid(request)
    items = get_eleves_by_code(logged_in)
    if items:
        item = items[0]
    else:
        item = None  # user = admin TODO

    # import pdb;pdb.set_trace()

    return {
        'page_title': u"Fiche d'inscription",
        'item': item,
        }


@view_config(route_name='last_connected',
        renderer='templates/last_connected.pt', permission='manage')
def last_connected(request):
    logged_in = authenticated_userid(request)
    items = get_eleves_by_last_connection()
   

    return {
        'page_title': u"Derniers connectés",
        'items': items,
        }


@view_config(route_name='login', renderer='templates/login.pt', permission='view')
@view_config(route_name='login_as', renderer='templates/login.pt', permission='view')
@forbidden_view_config(renderer='templates/login.pt')
def login(request):
    current_route_path = request.current_route_path()
    if 'login_as' in current_route_path:
        login = request.matchdict['login']
        login_url = request.route_url('login_as', login=login)
    else:
        login = ''
        login_url = request.route_url('login')

    referrer = request.url
    if referrer == login_url:
        referrer = '/' # never use the login form itself as came_from

    came_from = request.params.get('came_from', referrer)

    message = ''
    password = ''

    if 'form.submitted' in request.params:
        login = request.params['login']
        password = request.params['password']
        results = get_eleves_by_code(login)
        if (results and results[0].motdepasse == password) or (login in USERS and USERS[login] == password):
            update_last_connection(login)
            headers = remember(request, login)
            return HTTPFound(location=came_from, headers=headers)
        else:
            message = u"L'identification a échoué, veuillez réessayer."

    return {
        'page_title': u"Se connecter",
        'message': message,
        'url': login_url,
        'came_from': came_from,
        'login': login,
        'password': password,
        'email_password_url': request.route_url('email_password')
        }


@view_config(route_name='logout')
def logout(request):
    headers = forget(request)
    request.session.flash(u"Vous avez bien été déconnecté.")
    return HTTPFound(location=request.route_url('login', login=''),
                     headers=headers)


@view_config(route_name='member_search',
        renderer='templates/member_search.pt', permission='manage')
def member_search(request):
    url = request.route_url('member_search')
    message = u''
    members = []
    name = u''
    if 'form.submitted' in request.params:
        name = request.params['name']
        members = get_eleves_by_name(name)

    return {
        'page_title': u"Rechercher un élève",
        'url': url,
        'message': message,
        'members': members,
        'name': name,
    }


@view_config(route_name='member_page',
        renderer='templates/member_page.pt', permission='manage')
def member_page(request):
    member_id = request.matchdict['member_id']
    url = request.route_url('member_page', member_id=member_id)
    message = u''
    results = get_eleves_by_code(member_id)
    if results:
        member = results[0]
        page_title = u"Fiche élève N° %s" % member_id
    else:
        message = u"Aucun élève ne correspond à ce code."
        page_title = u"Aucun élève trouvé"
        member = None
    return {
        'page_title': page_title,
        'url': url,
        'member': member,
        'message': message,
        'member_search_url': request.route_url('member_search'),
    }


@view_config(route_name='reglement',
        renderer='templates/reglement.pt', permission='view')
def reglement(request):

    def get_cb_maxdate():
        today = date.today()
        cb_maxdate = today + relativedelta(months=+2)
        return cb_maxdate.strftime('%m%y')

    def get_schedule_dates():
        today = date.today()
        second_reglement = today + relativedelta(months=+1)
        third_reglement = today + relativedelta(months=+2)
        return [today.strftime('%d/%m/%Y'),
                second_reglement.strftime('15/%m/%Y'),
                third_reglement.strftime('15/%m/%Y')]

    def calc_montant_nfois(total, display):
        """Divise total par 3, et retourne le binôme suivant :
           [ ([int] résultat entier + reste), ([str10] résultat entier avec zéros devant) ]
           display est utilisé pour produire soit des paramètres (display = 0), soit des
           chaînes d'affichage (display = 1).
        """
        a = 0
        b = ''
        zeros = ''
        total = int(total)
        a = total / 3 + total % 3
        b = str(total / 3)
        if display == 0:
            b = b.zfill(10)
        elif display == 1:
            a = str(a)
            a = a[:-2] + u',' + a[-2:] + u' €'
            b = b[:-2] + u',' + b[-2:] + u' €'

        return [a, b]

    url = request.route_url('reglement')
    logged_in = authenticated_userid(request)
    mttotal = request.params['mttotal']
    nfois = request.params['nfois']
    reference = u''
    sum_to_pay = 0.0
    total = 0
    pay_ok = False
    cb_maxdate = get_cb_maxdate()
    schedule_dates = None
    schedule_sums = None

    if 'calculate-reglement-form.submitted' in request.params:
        pay_ok = True
        nfois = request.params['nfois']
        sum_to_pay = float(mttotal)
        reference = bill.DOSSIER + '/'
        total = int(math.ceil(to_decimal(100.)*to_decimal(sum_to_pay)))  # was montantcmd
        if nfois == u'3':
            # Splitted reglement
            if total < 30000:
                pay_ok = False
            else:
                sums = calc_montant_nfois(total, 0)
                today = strftime('%d-%m-%Y')
                reference += today + 'IBS_2MONT' + sums[1] + 'IBS_NBPAIE02IBS_FREQ01IBS_QUAND00'
                schedule_dates = get_schedule_dates()
                schedule_sums = calc_montant_nfois(int(sums[0])+int(sums[1])+int(sums[1]), 1)

    return {
        'page_title': u"Régler mes factures",
        'url': url,
        'reference': reference,
        'sum_to_pay': sum_to_pay,
        'total': total,
        'nfois': nfois,
        'pay_ok': pay_ok,
        'cb_maxdate': cb_maxdate,
        'logged_in_email': get_member_info(logged_in)['email'],
        'schedule_dates': schedule_dates,
        'schedule_sums': schedule_sums,
    }



